﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using GameCreator.Camera;
using GameCreator.Core.Hooks;
using Gp.Scripts.Core;
using Gp.Scripts.GUI;
using PixelCrushers.DialogueSystem;
using QFramework;
using UnityEngine;

namespace Gp.Scripts.Core {
    [AutoLoad]
    public class ConversationSystem : BaseGameSystem {
        public DialogueModel Model { get; private set; }

        protected override void OnInit()
        {
            RegisterData(new DialogueModel());

            // 添加任务开始与完成通知
            QuestLog.SetQuestEntryStateOverride = (quest, number, state) => {
                if (state == QuestLog.StateToString(QuestState.Active) &&
                    QuestLog.GetQuestEntryState(quest, number) != QuestState.Active) {
                    if (QuestLog.GetQuestState(quest) == QuestState.Unassigned) {
                        QuestLog.SetQuestState(quest,QuestState.Active);
                    }
                    DialogueManager.ShowAlert("任务开始：" + QuestLog.GetQuestEntry(quest, number));
                }
                else if (state == QuestLog.StateToString(QuestState.Success) && 
                         QuestLog.GetQuestEntryState(quest, number) != QuestState.Success) {
                    DialogueManager.ShowAlert("任务完成：" + QuestLog.GetQuestEntry(quest, number));
                }

                QuestLog.DefaultSetQuestEntryState(quest, number, state);
            };
            
            
            QuestLog.SetQuestStateOverride = (quest, state) => {
                if (state == QuestLog.StateToString(QuestState.Active) &&
                    QuestLog.GetQuestState(quest) != QuestState.Active) {
                    DialogueManager.ShowAlert("任务开始：" + quest);
                }
                else if (state == QuestLog.StateToString(QuestState.Success) && 
                         QuestLog.GetQuestState(quest) != QuestState.Success) {
                    DialogueManager.ShowAlert("任务完成：" + quest);
                }
                QuestLog.DefaultSetQuestState(quest, state);
            };



            const BindingFlags flags =
                BindingFlags.Static
                | BindingFlags.Public
                | BindingFlags.NonPublic
                | BindingFlags.DeclaredOnly;

            // 注册lua函数
            var registers = GetType().Assembly.GetTargetType(baseClass: typeof(LuaRegister));

            foreach (var method in registers.SelectMany(type => type.GetMethods(flags))) {
                var foo = method.GetCustomAttribute<LuaFunctionAttribute>();
                if (foo == null) continue;

                Lua.RegisterFunction(method.Name, null, method);

                foreach (var fooName in foo.Names) {
                    Lua.RegisterFunction(fooName, null, method);
                }
            }
            
        }

        public override void OnStart() {
            // DialogueManager.Instance.conversationStarted += _ => {
            //     // 切换为UI模式
            //     Global.Get<InputLayerSystem>().SwitchToUILayer(this);
            //
            //     var target = DialogueManager.Instance.lastConversationStarted;
            //     
            //     // Global.Get<GUIManager>().SwitchCanvasDisplay(UIGroup.Dialogue);
            //
            //     Model.OnConversationStarted(target);
            //     
            // };
            //
            //
            // DialogueManager.Instance.conversationEnded += _ => {
            //     // 切回上一级
            //     Global.Get<InputLayerSystem>().SwitchToBase(this);
            //
            //     var target = DialogueManager.Instance.lastConversationEnded;
            //     
            //     // Global.Get<GUIManager>().SwitchToLastLayer();
            //
            //     if (HookCamera.Instance != null) {
            //         CameraController cameraController = HookCamera.Instance.Get<CameraController>();
            //         if (cameraController != null && cameraController.currentCameraMotor != CameraMotor.MAIN_MOTOR) {
            //             cameraController.ChangeCameraMotor(
            //                 CameraMotor.MAIN_MOTOR,
            //                 0.2f
            //             );
            //         }
            //     }
            //     Model.OnConversationEnded(target);
            // };

        }

        public void StartConversation(string characterName) {
            var model = Model;

            // 获得该角色的所有对话
            var infoList = model.GetConversationInfoList(characterName);

            var info = FilterConversations(infoList);
            if (info == null) return;

            try {
                DialogueManager.Instance.StartConversation(info.ConversationTitle);
            }
            catch (Exception e) {
                Debug.LogError("对话脚本未正确执行：" + e);
                throw;
            }
        }
        
        public void StartSceneConversation(string characterName,Transform barker) {
            var model = Model;

            // 获得该角色的所有对话
            var infoList = model.GetConversationInfoList(characterName);

            var info = ResolveInfoList(infoList.Where(x => x.IsScene).ToList());
            if (info == null) return;

            try {
                DialogueManager.Instance.Bark(info.ConversationTitle,barker);
            }
            catch (Exception e) {
                Debug.LogError("对话脚本未正确执行：" + e);
                throw;
            }
        }


        /// <summary>
        /// 从一组对话中筛选出唯一的一条对话
        /// </summary>
        /// <returns></returns>
        private ConversationInfos FilterConversations(IEnumerable<ConversationInfos> infos) {
            var res = infos
                // 筛除非激活任务对话
                .Where(x => !x.HasQuest || !QuestLog.IsQuestUnassigned(x.Quest) 
                                        || x.IsTrigger || x.IsActivator)
                
                
                // 筛除激活器
                .Where (x => !x.IsActivator || QuestLog.IsQuestUnassigned(x.Quest))
                
                
                // 筛除只能触发一次的对话
                .Where(x => !x.IsOnce || Model.ConversationCount(x.ConversationTitle) <= 1)
                


                // 筛除任务触发器对话
                .Where(x => true)
                
                // 筛除非激活子任务对话
                .Where(x => !x.HasQuestEntry && QuestLog.GetQuestEntry(x.Quest, x.QuestEntry) !=
                    QuestLog.StateToString(QuestState.Unassigned))
                
                // 筛出场景对话
                // todo:我这里不筛出场景对话了，之后要筛掉直接激活
                // .Where(x => !x.IsScene)
                
                
                // 筛除不满足对话节点condition的对话
                .Where(x => DialogueManager.Instance.ConversationHasValidEntry(x.ConversationTitle))
                .ToList();

            return ResolveInfoList(res);
        }


        private static ConversationInfos ResolveInfoList(List<ConversationInfos> list) {
            if (list.Count > 1) {
                var message =
                    list.Aggregate("找到多段符合条件对话：\n", (current, x) => current + $"\t{x.ConversationTitle}\n");
                Debug.Log(message);
            }

            list.Sort((x, y) => x.Priority - y.Priority);
            return list.FirstOrDefault();
        }


        public ConversationInfos ResolveConversation(string conversationTitle) {
            return Model.ResolveConversation(conversationTitle);
        }

        public bool HasCharacter(string characterName) {
            return Model.HasCharacter(characterName);
        }
    }
}